package org.yeasy.common.util;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.ReflectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageInfo;
import org.yeasy.common.constant.CommonConstant;
import org.yeasy.eval.annotation.ValueSource;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * The type Json bean util.涉及json与bean转换的工具
 *
 * @author yangyishe
 * @date 2022年11月02日 16:36
 */
public class JsonBeanUtil {
    /**
     * Convert entity 2 json by annotation alias json object.将实体类根据注解别名转换为json对象
     *
     * @param <T>             the type parameter
     * @param <U>             the type parameter
     * @param entity          the entity
     * @param annotationClass the annotation class
     * @return the json object
     * @author yangyishe
     * @date 2022年11月02日 16:32
     */
    public static<T,U extends Annotation> JSONObject convertEntity2JsonByAnnotationAlias(T entity, Class<U> annotationClass){
        JSONObject mResult= (JSONObject) JSON.toJSON(entity);

        List<Field> lstField= Arrays.stream(entity.getClass().getDeclaredFields())
                .filter(o->o.getAnnotation(annotationClass)!=null).collect(Collectors.toList());
        for (Field field : lstField) {
            U annotation=field.getAnnotation(annotationClass);
            String annotationValue= ReflectUtil.invoke(annotation, CommonConstant.VALUE);
            if(CharSequenceUtil.isNotEmpty(annotationValue)){
                mResult.put(annotationValue, CommonBeanUtil.invokeGetter(entity,field.getName()));
            }
        }

        return mResult;
    }

    /**
     * Convert entity page 2 json by annotation alias page info.
     *
     * @param <T>             the type parameter
     * @param <U>             the type parameter
     * @param pageInfo        the page info
     * @param annotationClass the annotation class
     * @return the page info
     * @author yangyishe
     * @date 2022年11月02日 16:42
     */
    public static<T,U extends Annotation> PageInfo<JSONObject> convertEntityPage2JsonByAnnotationAlias(PageInfo<T> pageInfo, Class<U> annotationClass){
        PageInfo<JSONObject> pageResult=new PageInfo<>();
        BeanUtil.copyProperties(pageInfo,pageResult);

        List<JSONObject> lstObj=pageInfo.getList().stream()
                .map(o-> JsonBeanUtil.convertEntity2JsonByAnnotationAlias(o, annotationClass)).collect(Collectors.toList());
        pageResult.setList(lstObj);

        return pageResult;
    }
}
